/* eslint-disable no-console */
function pickJsonObj(value: string) {
  try {
    return JSON.parse(value)
  } catch {
    return null
  }
}
// UniApp.SocketTask
class WebSocketClient {
  url: string
  socket: Nullable<UniNamespace.SocketTask> = null
  isReconnecting = false
  reconnectInterval = 3000 // 重连间隔，单位毫秒
  heartBeatInterval = 5000 // 心跳间隔，单位毫秒
  pingTimeoutDuration = 1000 // 超过这个时间，后端没有返回pong，则判定后端断线了。
  heartBeatTimer: Nullable<TimeoutHandle> = null
  pingTimeout: Nullable<TimeoutHandle> = null
  destroy = false // 是否销毁
  constructor(url: string) {
    this.url = url
  }

  connect() {
    this.socket = uni.connectSocket({
      url: this.url,
      complete: () => {
        console.log('WebSocket连接已建立')
        this.startHeartBeat()
      },
    })
    this.initEventListeners()
  }

  initEventListeners() {
    this.socket?.onOpen(() => {
      // WebSocket连接已打开
      this.onConnected()
    })

    this.socket?.onMessage((res) => {
      const obj = pickJsonObj(res.data)
      if (obj.type === 'pong') {
        // 收到pong消息，心跳正常，无需处理
        this.resetPingTimeout() // 重置计时
      } else {
        // 处理其他消息
        this.onMessage(res.data)
      }
    })

    this.socket?.onClose(() => {
      // WebSocket连接已关闭
      if (this.destroy) {
        this.onClosed()
        return
      }
      this.stopHeartBeat()
      if (!this.isReconnecting) {
        this.reconnect()
      }
    })
  }

  sendMessage(message: string) {
    if (this.socket) {
      this.socket.send({
        data: message,
      })
    }
  }

  onMessage(message: string) {
    // 处理收到的消息
    console.log('message:', message)
  }
  // 心跳检测
  startHeartBeat() {
    this.heartBeatTimer = setInterval(() => {
      this.sendMessage(
        JSON.stringify({
          type: 'ping',
        })
      ) // 发送ping消息
      this.pingTimeout = setTimeout(() => {
        // 未收到pong消息，尝试重连...
        this.reconnect()
      }, this.pingTimeoutDuration)
    }, this.heartBeatInterval)
  }
  // 关闭心跳
  stopHeartBeat() {
    if (this.heartBeatTimer) {
      clearInterval(this.heartBeatTimer)
    }
  }
  // 重连
  reconnect() {
    this.isReconnecting = true
    setTimeout(() => {
      this.onReconnect()
      this.connect()
      this.isReconnecting = false
    }, this.reconnectInterval)
  }

  resetPingTimeout() {
    this.pingTimeout && clearTimeout(this.pingTimeout) // 重置计时
  }
  // 关闭连接
  close() {
    this.destroy = true
    this.stopHeartBeat()
    if (this.socket) {
      this.socket?.close({})
      this.socket = null
    }
  }
  /**
   * 重连时触发
   */
  onReconnect() {
    console.log('尝试重连...')
  }
  /**
   * 连接成功时触发
   */
  onConnected() {
    console.log('WebSocket连接已打开')
  }
  /**
   * 断开时触发
   */
  onClosed() {
    console.log('已断开连接')
  }
}

export default WebSocketClient
